package org.heydr.datacenter.guard;

import java.util.Calendar;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@Service
public class Guard {
	private static Logger logger = LoggerFactory.getLogger(Guard.class);
	
	private Map<String,Long> slavers = new ConcurrentHashMap<String, Long>();
	
	public synchronized void removeNode(String ip){
		slavers.remove(ip);
		logger.info("node "+ip+" has been remove.");
	}
	
	public void heartBeat(String ip){
		if(slavers.containsKey(ip))
			slavers.put(ip, Calendar.getInstance().getTimeInMillis());
		else
			addNode(ip);
	}
	
	@Scheduled(cron="0/5 * * * * *")
	public void inspect(){
		long now = Calendar.getInstance().getTimeInMillis();
		int total = slavers.size();
		for(Entry<String, Long> entry : slavers.entrySet()){
			Long lastTime = entry.getValue();
			if((now - lastTime) > 30000l){
				String ip = entry.getKey();
				logger.info("node "+ ip + " was lost.");
				removeNode(ip);
			}
		}
		int alive = slavers.size();
		logger.info("finish an inspection. alive :"+alive + " lost:"+(total-alive));
	}
	
	public boolean addNode(String ip){
		if(slavers.containsKey(ip)){
			logger.info("node "+ip+" is already existed.");
			return Boolean.FALSE;
		}
		else{
			logger.info("a new node :"+ip+" is join! current slaves size:"+slavers.size());
			slavers.put(ip, Calendar.getInstance().getTimeInMillis());
			return Boolean.TRUE;
		}
	}
	
}
